#include<initializer_list>
#include<assert.h>
#include<iostream>
using namespace std;

template<class T>
class vector
{
public:
    vector()
        :_start(nullptr), _endofstorage(nullptr), _finish(nullptr)
    {
        cout << "vector()" << endl;
    }
    vector(const vector<T>& v)
        :_start(nullptr), _endofstorage(nullptr), _finish(nullptr)
    {
        cout << "vector(const vector<T>& v)" << endl;
        for (auto& x : v)
        {
            push_back(x);
        }
    }
    vector(const initializer_list<T>& lt)
        :_start(nullptr), _endofstorage(nullptr), _finish(nullptr)
    {
        cout << "vector(const initializer_list<T>& lt)" << endl;
        for (auto& x : lt)
            push_back(x);
    }


    template<class InputIterator>
    vector(InputIterator first, InputIterator last)
        :_start(nullptr), _endofstorage(nullptr), _finish(nullptr)
    {
        cout << " vector(InputIterator first, InputIterator last)" << endl;
        while (first != last)
        {
            push_back(*first);
            first++;
        }
    }
    vector<T>& operator=(const vector<T>& v)
    {
        cout << "vector<T>& operator=(const vector<T>& v)" << endl;
        if (this != &v)
        {
            delete[] _start;
            _start = new T[v.capacity()];
            for (int i = 0; i < v.size(); i++)
            {
                _start[i] = v[i];
            }
            _finish = _start + v.size();
            _endofstorage = _start + v.capacity();
        }
        return *this;
    }

    //右值引用版本
    vector(vector<T>&& v) 
        :_start(nullptr), _endofstorage(nullptr), _finish(nullptr)
    {
        cout << "vector(vector<T>&& v)" << endl;
        Swap(v);
    }
    vector<T>& operator=(vector<T>&& v)
    {
        cout << "vector<T>& operator=(const vector<T>&& v)" << endl;
        if (this != &v)
        {
            Swap(v);
        }
        return *this;
    }
    void Swap(vector<T>& v) const
    {
        ::swap(_start, v._start);
        ::swap(_endofstorage, v._endofstorage);
        ::swap(_finish, v._finish);
    }
    bool empty() const 
    {
        return _start == _finish;
    }
    size_t size() const
    {
        return _finish - _start;
    }
    size_t capacity() const
    {
        return _endofstorage - _start;
    }
    ~vector()
    {
        if (_start)
            delete[] _start;
        _start = _endofstorage = _finish = nullptr;
    }
    void resize(size_t n, T val = T())
    {
        if (n < size()) //缩小有效元素个数
        {
            _finish = _start + n;
        }
        else
        {
            if (n > capacity())
            {
                reserve(n);
            }
            while (_finish != _start + n)
            {
                *_finish = val;
                _finish++;
            }
        }
    }
    void reserve(size_t space)
    {
        if (space > capacity())
        {
            T* newSpace = new T[space];
            int size = this->size();
            for (int i = 0; i < size; i++)
            {
                newSpace[i] = _start[i];
            }
            delete[] _start;
            _start = newSpace;
            _finish = _start + size;
            _endofstorage = _start + space;
        }
    }
    void push_back(const T& val)
    {
        if (_endofstorage == _finish)
        {
            reserve(this->capacity() == 0 ? 4 : 2 * this->capacity());
        }
        *_finish = val;
        _finish++;
    }
    void pop_back()
    {
        assert(!empty());
        _finish--;
    }

    //迭代器相关
    typedef T* iterator;
    typedef const T* const_iterator;

    iterator begin()
    {
        return _start;
    }
    iterator end()
    {
        return _finish;
    }
    const_iterator begin() const
    {
        return _start;
    }
    const_iterator end() const
    {
        return _finish;
    }
    T& operator[](size_t pos)
    {
        assert(pos < size());
        return _start[pos];
    }
    const T& operator[](size_t pos) const
    {
        assert(pos < size());
        return _start[pos];
    }
private:
    iterator _start;
    iterator _endofstorage;
    iterator _finish;
};

template<class T>
void Print(const vector<T>& v)
{
    for (auto& x : v)
        cout << x << "   ";
    cout << endl;
}

void test_vector1()
{
    vector<int> v;
    v.push_back(1);
    v.push_back(2);
    v.push_back(3);
    v.push_back(4);
    v.push_back(5);
    v.push_back(6);

    for (size_t i = 0; i < v.size(); ++i)
    {
        cout << v[i] << " ";//1 2 3 4 5 6
    }
    cout << endl;

    vector<int>::iterator it = v.begin();
    while (it != v.end())
    {
        cout << *it << " ";//1 2 3 4 5 6
        ++it;
    }
    cout << endl;

    for (auto e : v)
    {
        cout << e << " ";//1 2 3 4 5 6
    }
    cout << endl;
}


void test_vector3()
{
    vector<int> v1;
    v1.push_back(1);
    v1.push_back(2);
    v1.push_back(3);
    v1.push_back(4);
    vector<int> v2(v1);
    for (auto e : v2)
        cout << e << " ";//1 2 3 4
    cout << endl;

    vector<int> v3;
    v3.push_back(10);
    v3.push_back(20);
    v3.push_back(30);

    v1 = v3;
    for (auto e : v1)
        cout << e << " ";//10 20 30
    cout << endl;
}

int main()
{
   /* vector<int> v{ 1,2,3 };
    vector<int> v2 = move(v);
    vector<int> v3;
    v3 = move(v2);
    Print(v3);*/
    test_vector1();
    //test_vector2();
    test_vector3();
    return 0;
}
